#include "pwm_driver.h"

QueueHandle_t pwm_queue_handle;
static TaskHandle_t pwm_handle;

static void example_ledc_W_init(void)
{
    // Prepare and then apply the LEDC PWM timer configuration
    ledc_timer_config_t ledc_red_timer = {
        .speed_mode       = LEDC_W_MODE,
        .timer_num        = LEDC_W_TIMER,
        .duty_resolution  = LEDC_W_DUTY_RES,
        .freq_hz          = LEDC_W_FREQUENCY,  // Set output frequency at 5 kHz
        .clk_cfg          = LEDC_AUTO_CLK
    };
    ESP_ERROR_CHECK(ledc_timer_config(&ledc_red_timer));

    // Prepare and then apply the LEDC PWM channel configuration
    ledc_channel_config_t ledc_red_channel = {
        .speed_mode     = LEDC_W_MODE,
        .channel        = LEDC_W_CHANNEL,
        .timer_sel      = LEDC_W_TIMER,
        .intr_type      = LEDC_INTR_DISABLE,
        .gpio_num       = LEDC_W_OUTPUT_IO,
        .duty           = 0, // Set duty to 0%
        .hpoint         = 0
    };
    ESP_ERROR_CHECK(ledc_channel_config(&ledc_red_channel));
}

static void example_ledc_CW_init(void)
{
    // Prepare and then apply the LEDC PWM timer configuration
    ledc_timer_config_t ledc_green_timer = {
        .speed_mode       = LEDC_CW_MODE,
        .timer_num        = LEDC_CW_TIMER,
        .duty_resolution  = LEDC_CW_DUTY_RES,
        .freq_hz          = LEDC_CW_FREQUENCY,  // Set output frequency at 5 kHz
        .clk_cfg          = LEDC_AUTO_CLK
    };
    ESP_ERROR_CHECK(ledc_timer_config(&ledc_green_timer));

    // Prepare and then apply the LEDC PWM channel configuration
    ledc_channel_config_t ledc_green_channel = {
        .speed_mode     = LEDC_CW_MODE,
        .channel        = LEDC_CW_CHANNEL,
        .timer_sel      = LEDC_CW_TIMER,
        .intr_type      = LEDC_INTR_DISABLE,
        .gpio_num       = LEDC_CW_OUTPUT_IO,
        .duty           = 0, // Set duty to 0%
        .hpoint         = 0
    };
    ESP_ERROR_CHECK(ledc_channel_config(&ledc_green_channel));
}

void pwm_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel,uint32_t duty)
{
    ledc_set_duty(speed_mode, channel, duty); /* 设置占空比 */
    ledc_update_duty(speed_mode, channel);    /* 更新占空比 */
}

void pwm_task()
{
    LOG_INFO("pwm_task : enter disp_loop()\n");
    pwm_queue_handle = xQueueCreate(10,sizeof(u32 *));

    u32 *send_buffer = NULL;
    while (1)
    {
        if(xQueueReceive(pwm_queue_handle,&send_buffer,portMAX_DELAY))
        {
            if (send_buffer != NULL)
            {
                pwm_set_duty(LEDC_W_MODE, LEDC_W_CHANNEL, send_buffer[0]);
                pwm_set_duty(LEDC_CW_MODE, LEDC_CW_CHANNEL, send_buffer[1]);
                //printf("send_buffer[0]:%ld,send_buffer[1] :%ld\n",send_buffer[0],send_buffer[1]);
                vPortFree(send_buffer);
            }
            send_buffer =NULL;
        }
    }
    
}


void device_pwm_init(void)
{
    printf("device_pwm_init():enter");
    example_ledc_W_init();
    example_ledc_CW_init();
    xTaskCreate(pwm_task, "pwm_task", PWM_LOGIC_SIZE, NULL, TASK_PROP_DISPLAY, &pwm_handle);
}